﻿using System.Collections;
using System.Collections.Generic;
using UBlockly.Compotent;
using UBlockly.Scriptable;
using UBlockly.Scriptable.Function;
using UnityEngine;
using UBlockly.UI;


    public sealed class NodePacker
    {
        private Node MainNode;
        private RectPacker[] packer;
//        private Node ParamNode;
        private Node DefaultParamNode;

        public NodePacker(Node mainNode ,ParamGetterCompotent paramGetter)
        {
            MainNode = mainNode;
            ILFunc il = null;
            string defaultFuncName = "";
            switch (mainNode.Scriptable.ParamType)
            {
                case ILFunResult.BoolR:
                    il = new BoolVoidILFunc();
                    defaultFuncName = "GetBool";
                    break;
                case ILFunResult.IntR:
                    il = new IntVoidILFunc();
                    defaultFuncName = "GetInt";
                    break;
                case ILFunResult.StringR:
                    il = new StringVoidILFunc();
                    defaultFuncName = "GetString";
                    break;
                default:
                    break;
            }

            if (il == null)
                return;
            
            NodeScriptable x = new NodeScriptable(il);
            x.BindFuncName(defaultFuncName, paramGetter.GetterValue);
            DefaultParamNode = new EmptyBlockNode(x);
            DefaultParamNode.BodyChangeNotify = mainNode.ResizeNode;
        }

        public void Init()
        {
            packer = new RectPacker[1];
            packer[0] = new RectPacker(GetPackAnchor(),MainNode.Scriptable.ParamType);
        }
        public Node GetParam(int index = 0)
        {
            var lst = MainNode.NodePacker.GetPackerRootTransform().childCount;
            var targetBlock = MainNode.NodePacker.GetPackerRootTransform().GetChild(lst-1).GetComponent<BlockObject>();
            if (targetBlock == null)
                return DefaultParamNode;
            return targetBlock.Node.Value;
        }

        public void PackNode(Node node, int index = 0)
        {
            node.Block.AttacthToBlock(GetPackAnchor(index));//设置物理挂载关系
            GetPackerRootTransform().GetChild(0).gameObject.SetActive(false);
            if (GetPackerRootTransform().childCount == 1)
            {
                GetPackerRootTransform().GetChild(0).gameObject.SetActive(true);
            }
            node.BodyChangeNotify = MainNode.ResizeNode;
            MainNode.ResizeNode();
        }

        public void UnPackNode(Transform rootTransform, int index = 0)
        {
            if (GetParam(index) != DefaultParamNode)
            {
                var blockTrans = GetParam(index).Block.transform;
                var pos = blockTrans.position;
                GetParam(index).Block.UnAttach(rootTransform);
                blockTrans.position = pos;
                blockTrans.localPosition += new Vector3(100,100);
            }

            if (GetParam(index) == DefaultParamNode)
            {
                GetPackerRootTransform().GetChild(0).gameObject.SetActive(true);
                MainNode.ResizeNode();
            }
        }

        public BlockAnchor GetPackAnchor(int index = 0)
        {
            return GetPackerRootTransform().GetComponent<BlockAnchor>();
        }

        public Transform GetPackerRootTransform()
        {
            if(MainNode == null || MainNode.Block == null)
                Debug.LogError($"whwww:{MainNode.Scriptable.GetFunc().FunName}");
            return MainNode.Block.Find("PackInfo");
        }

        public IRectPacker[] GetPackers()
        {
            return packer;
        }
    }

public interface IRectPacker
{ 
    BlockAnchor BlockAnchor { get; }
    ILFunResult ParamType { get; }
}

public sealed class RectPacker : IRectPacker
{
    private BlockAnchor blockAnchor;
    private ILFunResult paramType;

    public BlockAnchor BlockAnchor => blockAnchor;
    public ILFunResult ParamType => paramType;

    public RectPacker(BlockAnchor anchor, ILFunResult ptype)
    {
        blockAnchor = anchor;
        paramType = ptype;
    }
}

public sealed class NodeSlot
{
    public NSlotPair GetPair(int index = 0)
    {
        return null;
    }
}
